﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Threading;
using WFNetLib.Forms;
using WFNetLib;
using WFNetLib.GSMModem;
using WFNetLib.Net;
using System.Net;
using System.Diagnostics;

namespace wap主题
{
    public class ReaderThread
    {
        public SerialPort Com;
        public Thread ReaderThreadIns = null;
        public static event strEventHandler AddLogEvent;//事件声明
        public static event intEventHandler FinishEvent;//事件声明
        public List<主题Data> Tasks;
#if DEBUG
        CommunicationDebugForm CommunicationDebugForm;
#endif


        GsmModem gsmModem;
        public string PortName;
        public int ComIndex;
        void OnAddLog(string strLog)
        {
            if (AddLogEvent != null)
            {
                AddLogEvent(this, new strEventArgs(strLog));
            }
        }
        void OnFinishEvent(int n)
        {
            if (FinishEvent != null)
            {
                FinishEvent(this, new intEventArgs(n));
            }
        }
        string processurl(string url)
        {
            url = url.Replace("%3A", ":");
            url = url.Replace("%2F", "/");
            url = url.Replace("%3F", "?");
            url = url.Replace("%3D", "=");
            url = url.Replace("%26", "&");
            return url;
        }
        public ReaderThread(SerialPort _Com, int index,List<主题Data> tasks)
        {
            Com = _Com;

#if DEBUG
            CommunicationDebugForm = new CommunicationDebugForm();
            //CommunicationDebugForm.IsClose = true;
            CommunicationDebugForm.Show();
            //CommunicationDebugForm.Hide();
            CommunicationDebugForm.Text = Com.PortName + "数据检测";
            gsmModem = new GsmModem(Com, CommunicationDebugForm);
            gsmModem.ProcessURL = new GsmModem.delegateProcessURL(processurl);
#else
            gsmModem = new GsmModem(Com);
#endif

            ComIndex = index;
            gsmModem.dIP[0] = 10;
            gsmModem.dIP[1] = 0;
            gsmModem.dIP[2] = 0;
            gsmModem.dIP[3] = 172;
            gsmModem.dPort = 80;
            gsmModem.AddLog += new strEventHandler(gsmModem_AddLog);
            Tasks = new List<主题Data>();
            foreach (主题Data d in tasks)
            {
                Tasks.Add(d);
            }
        }

        void gsmModem_AddLog(object sender, strEventArgs e)
        {
            OnAddLog(e.strArg);
        }
        public void ReaderThreadStart()
        {
            ReaderThreadIns = new Thread(new ThreadStart(ReaderProc));
            ReaderThreadIns.Name = "主题" + Com.PortName;
            PortName = Com.PortName;
            ReaderThreadIns.Start();
            OnAddLog("任务开始");
        }
        private void ReaderProc()
        {
            主题Data task;
            try
            {
                while (true)
                {
                    StringBuilder no = new StringBuilder();
                    int err = 0;
                    try
                    {
                        Com.Open();
                        //Com.RtsEnable = true;
                    }
                    catch
                    {
                        OnAddLog("串口无法打开,请终止软件");
                        OnFinishEvent((int)FinishType.Unkown);
                        break;
                    }
                    OnAddLog("开始初始化");
                    if (!gsmModem.InitGSMModem())
                    {
                        break;
                    }
                    OnAddLog("初始化成功");
                    OnAddLog("开始拨号");
                    if (!gsmModem.InitPPPConnect())
                    {
                        break;
                    }
                    OnAddLog("拨号成功");
                    object o;
                    string str = "";  
                    string strLink;
                    string post;
                    string name;
                    string value;
                    Http http = null;
                    while(true)
                    {
                        if (Tasks.Count == 0)
                            break;
                        task = Tasks[0];
                        err++;
                        if (err > 5)
                        {
                            Tasks.RemoveAt(0);
                            no.Append(task.名称);
                            no.Append("   失败\r\n");
                            if (Tasks.Count == 0)
                                break;
                            task = Tasks[0];
                        }
                        gsmModem.finishper = 100;
                        gsmModem.httpHeader = new WebHeaderCollection();
                        gsmModem.httpHeader[HttpRequestHeader.UserAgent] = task.ua;
                        gsmModem.httpHeader[HttpRequestHeader.Accept] = "text/html";
                        gsmModem.httpHeader[HttpRequestHeader.AcceptEncoding] = "utf-8";
                        gsmModem.httpHeader[HttpRequestHeader.AcceptLanguage] = "zh-CN, en-US";
                        gsmModem.url = task.wap链接地址;
                        gsmModem.cookies = new CookieCollection();
                        if (!gsmModem.TCPRead())
                        {
                            OnAddLog("获得tcp数据失败!");
                            //OnFinishEvent((int)FinishType.Unkown);
                            continue;
                        }
                        o = gsmModem.TCPData.oTCPDatas;
                        if (o == null)
                            continue;
                        http = (Http)o;
                        if (http.ContentDatas.Count == 0)
                            continue;
                        str = HttpStatic.ContentToStr(http);
                        CommunicationDebugForm.ExternShowRx(http.strHttpHeader);
                        CommunicationDebugForm.ExternShowRx(str);
                        OnAddLog("获得订购页面");
                        int nCom = 0, nCom1 = 0;
                        while (true)
                        {
                            nCom = str.IndexOf("<a href=\"", nCom);
                            if (nCom == -1)
                            {
                                break;
                            }
                            nCom1 = str.IndexOf("</a>", nCom);
                            if (nCom1 == -1)
                            {
                                break;
                            }
                            if (str.IndexOf("订购", nCom, nCom1 - nCom) == -1)
                            {
                                nCom = nCom1 + "</a>".Length;
                            }
                            else
                                break;
                        }
                        if (nCom == -1 || nCom1 == -1)
                        {
                            OnAddLog("未找到订购链接");
                            nCom = 0;
                            nCom1 = 0;
                            while (true)
                            {
                                nCom = str.IndexOf("<a href=\"", nCom);
                                if (nCom == -1)
                                {
                                    break;
                                }
                                nCom1 = str.IndexOf("</a>", nCom);
                                if (nCom1 == -1)
                                {
                                    break;
                                }
                                if (str.IndexOf("下载", nCom, nCom1 - nCom) == -1)
                                {
                                    nCom = nCom1 + "</a>".Length;
                                }
                                else
                                    break;
                            }
                            if (nCom == -1 || nCom1 == -1)
                            {
                                OnAddLog("未找到下载链接");
                                if (str.IndexOf("作品详情") != -1)
                                {
                                    no.Append(task.名称);
                                    no.Append("   ua不正确\r\n");
                                    Tasks.RemoveAt(0);
                                    err = 0; 
                                }
                                continue;
                            }
                            nCom = 0;
                            nCom1 = 0;
                            while (true)
                            {
                                nCom = str.IndexOf("<a href=\"", nCom);
                                if (nCom == -1)
                                {
                                    break;
                                }
                                nCom1 = str.IndexOf("</a>", nCom);
                                if (nCom1 == -1)
                                {
                                    break;
                                }
                                if (str.IndexOf("下载", nCom, nCom1 - nCom) == -1)
                                {
                                    nCom = nCom1 + "<a href=\"".Length;
                                }
                                else
                                    break;
                            }
                            if (nCom == -1 || nCom1 == -1)
                            {
                                OnAddLog("未找到下载链接");
                                continue;
                            }
                            nCom = nCom + "<a href=\"".Length;
                            strLink = str.Substring(nCom, str.IndexOf('"', nCom) - nCom);
                            strLink = strLink.Replace("../", "");
                            gsmModem.url = strLink;
                            gsmModem.finishper = task.per;
                            OnAddLog("开始下载");
                            if (!gsmModem.TCPRead())
                            {
                                OnAddLog("获得tcp数据失败!");
                                continue;
                            }
                            o = gsmModem.TCPData.oTCPDatas;
                            if (o == null)
                                continue;
                            http = (Http)o;
                            if (http.ContentDatas.Count == 0)
                                continue;
                            str = HttpStatic.ContentToStr(http);
                            CommunicationDebugForm.ExternShowRx(http.strHttpHeader);
                            CommunicationDebugForm.ExternShowRx(str);
                            OnAddLog("下载完成");
                            Tasks.RemoveAt(0);
                            err = 0;                            
                            continue;
                        }
                        nCom = nCom + "<a href=\"".Length;
                        strLink = str.Substring(nCom, str.IndexOf('"', nCom) - nCom);
                        strLink = strLink.Replace("../", "");
                        gsmModem.url = "http://211.138.238.8/wap/" + strLink;                        
                        if (!gsmModem.TCPRead())
                        {
                            OnAddLog("获得tcp数据失败!");
                            //OnFinishEvent((int)FinishType.Unkown);
                            continue;
                        }
                        o = gsmModem.TCPData.oTCPDatas;
                        if (o == null)
                            continue;
                        http = (Http)o;
                        if (http.ContentDatas.Count == 0)
                            continue;
                        str = HttpStatic.ContentToStr(http);
                        CommunicationDebugForm.ExternShowRx(http.strHttpHeader);
                        CommunicationDebugForm.ExternShowRx(str);
                        nCom = 0;
                        nCom1 = 0;
                        while (true)
                        {
                            nCom = str.IndexOf("<anchor>", nCom);
                            if (nCom == -1)
                            {
                                break;
                            }
                            nCom1 = str.IndexOf("</anchor>", nCom);
                            if (nCom1 == -1)
                            {
                                break;
                            }
                            if (str.IndexOf("我要点播", nCom, nCom1 - nCom) == -1)
                            {
                                nCom = nCom1 + "</anchor>".Length;
                            }
                            else
                                break;
                        }
                        if (nCom == -1 || nCom1 == -1)
                        {
                            OnAddLog("未找到点播链接");
                            continue;
                        }
                        nCom = str.IndexOf("<go sendreferer=\"true\" href=\"", nCom);
                        if (nCom == -1)
                        {
                            OnAddLog("未找到点播链接");
                            continue;
                        }
                        nCom = nCom + "<go sendreferer=\"true\" href=\"".Length;
                        strLink = str.Substring(nCom, str.IndexOf('"', nCom) - nCom);
                        strLink = WFNetLib.Strings.StringsFunction.strDecode(strLink);
                        gsmModem.url = strLink;
                        nCom = str.IndexOf("<postfield name=\"", nCom);
                        if (nCom == -1)
                        {
                            OnAddLog("未找到点播链接");
                            continue;
                        }
                        nCom = nCom + "<postfield name=\"".Length;
                        name = str.Substring(nCom, str.IndexOf('"', nCom) - nCom);
                        nCom = str.IndexOf("value=\"", nCom);
                        if (nCom == -1)
                        {
                            OnAddLog("未找到点播链接");
                            continue;
                        }
                        nCom = nCom + "value=\"".Length;
                        value = str.Substring(nCom, str.IndexOf('"', nCom) - nCom);
                        post = "name=" + name + "&value=" + value;
                        Debug.WriteLine("post=" + post);
                        gsmModem.PostTx = new List<byte>(Encoding.ASCII.GetBytes(post));
                        gsmModem.httpHeader[HttpRequestHeader.ContentLength] = post.Length.ToString();
                        gsmModem.httpHeader[HttpRequestHeader.ContentType] = "Application";
                        if (!gsmModem.TCPRead("POST"))
                        {
                            OnAddLog("获得tcp数据失败!");
                            //OnFinishEvent((int)FinishType.Unkown);
                            continue;
                        }
                        o = gsmModem.TCPData.oTCPDatas;
                        if (o == null)
                            continue;
                        http = (Http)o;
                        if (http.ContentDatas.Count == 0)
                            continue;
                        str = HttpStatic.ContentToStr(http);
                        CommunicationDebugForm.ExternShowRx(http.strHttpHeader);
                        CommunicationDebugForm.ExternShowRx(str);
                        OnAddLog("获得点播页面!");
                        if (str.IndexOf("对不起，因服务提供商") != -1 && str.IndexOf("通讯故障，服务暂时无法完成") != -1)
                        {
                            OnAddLog(task.名称 + "暂时无法提供服务");
                            continue;
                        }
                        nCom = 0;
                        nCom1 = 0;
                        while (true)
                        {
                            nCom = str.IndexOf("<a href=\"", nCom);
                            if (nCom == -1)
                            {
                                break;
                            }
                            nCom1 = str.IndexOf("</a>", nCom);
                            if (nCom1 == -1)
                            {
                                break;
                            }
                            if (str.IndexOf("下载", nCom, nCom1 - nCom) == -1)
                            {
                                nCom = nCom1 + "<a href=\"".Length;
                            }
                            else
                                break;
                        }
                        if (nCom == -1 || nCom1 == -1)
                        {
                            OnAddLog("未找到下载链接");
                            continue;
                        }
                        nCom = nCom + "<a href=\"".Length;
                        strLink = str.Substring(nCom, str.IndexOf('"', nCom) - nCom);
                        strLink = strLink.Replace("../", "");
                        gsmModem.url =strLink;
                        gsmModem.finishper = task.per;
                        OnAddLog("开始下载");
                        if (!gsmModem.TCPRead())
                        {
                            OnAddLog("获得tcp数据失败!");                            
                            continue;
                        }
                        o = gsmModem.TCPData.oTCPDatas;
                        if (o == null)
                            continue;
                        http = (Http)o;
                        if (http.ContentDatas.Count == 0)
                            continue;
                        str = HttpStatic.ContentToStr(http);
                        CommunicationDebugForm.ExternShowRx(http.strHttpHeader);
                        CommunicationDebugForm.ExternShowRx(str);
                        OnAddLog("下载完成");
                        Tasks.RemoveAt(0);
                        err = 0;
                    }                 
                    OnAddLog("关闭连接");

                    if (!gsmModem.pppClose())
                    {
                        OnAddLog("ppp关闭失败");
                    }
                    else
                    {
                        OnAddLog("ppp关闭成功");
                    }
                    OnAddLog("完成所有任务");
                    if (no.Length != 0)
                    {
                        OnAddLog("此通道错误任务信息如下:\r\n");
                        OnAddLog(no.ToString());
                        OnFinishEvent((int)FinishType.Error);
                    }
                    else
                        OnFinishEvent((int)FinishType.Finish);
                    Com.Close();
                    return;
                }
                OnFinishEvent((int)FinishType.Error);
                Com.Close();
            }
            catch (System.Exception ex)
            {
                if (!gsmModem.pppClose())
                {
                    OnAddLog("ppp关闭失败");
                }
                else
                {
                    OnAddLog("ppp关闭成功");
                }
                OnAddLog("<未知退出>" + ex.Message);
                OnFinishEvent((int)FinishType.Unkown);
                if(Com.IsOpen)
                    Com.Close();
                return;
            }            
        }
    }
    public enum FinishType
    {
        Finish = 0,
        DoAgain = 1,
        Unkown = 2,
        Error=3
    }
}
